lib/kargs: Make API public and upstream new rpm-ostree APIs
authorAllen Bai <abai@redhat.com>
Tue, 28 May 2019 18:02:54 +0000 (14:02 -0400)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 18 Jun 2019 14:29:14 +0000 (14:29 +0000)
This change makes public the current kargs API in src/libostree/ostree-kernel-args.c
and adds documentations.

Upstreams the new kargs API from rpm-ostree/src/libpriv/rpmostree-kargs-process.c

Merges libostree_kernel_args_la_SOURCES to libostree_1_la_SOURCES in Makefile-libostree.am

Upstreams tests/check/test-kargs.c from rpm-ostree.

Closes: #1833
Closes: #1869
Approved by: jlebon

22 files changed:
Makefile-libostree-defines.am
Makefile-libostree.am
Makefile-ostree.am
Makefile-tests.am
apidoc/Makefile.am
apidoc/ostree-sections.txt
src/libostree/libostree-devel.sym
src/libostree/ostree-bootloader-uboot.c
src/libostree/ostree-kernel-args.c
src/libostree/ostree-kernel-args.h
src/libostree/ostree-sysroot-deploy.c
src/libostree/ostree-sysroot-private.h
src/libostree/ostree-sysroot.c
src/libostree/ostree.h
src/libotutil/ot-tool-util.c
src/libotutil/ot-tool-util.h
src/libotutil/otutil.h
src/ostree/ot-admin-builtin-deploy.c
src/ostree/ot-admin-builtin-unlock.c
src/ostree/ot-admin-instutil-builtin-set-kargs.c
tests/.gitignore
tests/test-kargs.c [new file with mode: 0644]

index 77748a41a189391339bb69d988483238081d6d60..060351571239541be8de4d2d27d1e7461226d6d6 100644 (file)
@@ -45,6 +45,7 @@ libostree_public_headers = \
        src/libostree/ostree-repo-finder-config.h \
        src/libostree/ostree-repo-finder-mount.h \
        src/libostree/ostree-repo-finder-override.h \
+       src/libostree/ostree-kernel-args.h \
        $(NULL)
 
 # This one is generated via configure.ac, and the gtk-doc
index dbc9ebb87934b0f4d24cae9a674d9d7deb6f5a64..0ea54cf871ba8619a6e86a38b76702e0c8686d6b 100644 (file)
@@ -21,8 +21,6 @@
 
 include Makefile-libostree-defines.am
 
-noinst_LTLIBRARIES += libostree-kernel-args.la
-
 
 if ENABLE_RUST
 bupsplitpath = @abs_top_builddir@/target/@RUST_TARGET_SUBDIR@/libbupsplit_rs.a
@@ -36,13 +34,6 @@ noinst_LTLIBRARIES += libbupsplit.la
 libbupsplit_la_SOURCES = src/libostree/bupsplit.h src/libostree/bupsplit.c
 endif # ENABLE_RUST
 
-libostree_kernel_args_la_SOURCES = \
-       src/libostree/ostree-kernel-args.h \
-       src/libostree/ostree-kernel-args.c \
-       $(NULL)
-libostree_kernel_args_la_CFLAGS = -I$(srcdir)/libglnx $(OT_INTERNAL_GIO_UNIX_CFLAGS)
-libostree_kernel_args_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS)
-
 lib_LTLIBRARIES += libostree-1.la
 
 libostreeincludedir = $(includedir)/ostree-1
@@ -147,6 +138,8 @@ libostree_1_la_SOURCES = \
        src/libostree/ostree-repo-finder-config.c \
        src/libostree/ostree-repo-finder-mount.c \
        src/libostree/ostree-repo-finder-override.c \
+       src/libostree/ostree-kernel-args.h \
+       src/libostree/ostree-kernel-args.c \
        $(NULL)
 if USE_LIBARCHIVE
 libostree_1_la_SOURCES += src/libostree/ostree-libarchive-input-stream.h \
@@ -191,7 +184,7 @@ libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/bsdiff -I$(srcdir)/libglnx -I$(
        $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(OT_DEP_LZMA_CFLAGS) $(OT_DEP_ZLIB_CFLAGS) $(OT_DEP_CRYPTO_CFLAGS) \
        -fvisibility=hidden '-D_OSTREE_PUBLIC=__attribute__((visibility("default"))) extern'
 libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions $(addprefix $(wl_versionscript_arg),$(symbol_files))
-libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la libostree-kernel-args.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) \
+libostree_1_la_LIBADD = libotutil.la libglnx.la libbsdiff.la $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) \
                         $(OT_DEP_LZMA_LIBS) $(OT_DEP_ZLIB_LIBS) $(OT_DEP_CRYPTO_LIBS)
 # Some change between rust-1.21.0-1.fc27 and rust-1.22.1-1.fc27.x86_64
 if ENABLE_RUST
index 8d352e38fd35a5ab6f9aa499e9f1aa38e2324933..92881a3190689db4c6b525a520087434de060be4 100644 (file)
@@ -125,7 +125,7 @@ ostree_bin_shared_ldadd = $(AM_LDFLAGS) libglnx.la libotutil.la libostree-1.la \
        $(OT_INTERNAL_GIO_UNIX_LIBS)
 
 ostree_CFLAGS = $(ostree_bin_shared_cflags)
-ostree_LDADD = $(ostree_bin_shared_ldadd) libbsdiff.la libostree-kernel-args.la $(LIBSYSTEMD_LIBS)
+ostree_LDADD = $(ostree_bin_shared_ldadd) libbsdiff.la $(LIBSYSTEMD_LIBS)
 
 
 if USE_CURL_OR_SOUP
index 2c0916f6204576983f5b91032f369eb06ae0b42b..ac59b94bed409bc54f8225b60da85bd41687e057 100644 (file)
@@ -246,7 +246,7 @@ endif
 _installed_or_uninstalled_test_programs = tests/test-varint tests/test-ot-unix-utils tests/test-bsdiff tests/test-mutable-tree \
        tests/test-keyfile-utils tests/test-ot-opt-utils tests/test-ot-tool-util \
        tests/test-gpg-verify-result tests/test-checksum tests/test-lzma tests/test-rollsum \
-       tests/test-basic-c tests/test-sysroot-c tests/test-pull-c tests/test-repo tests/test-include-ostree-h
+       tests/test-basic-c tests/test-sysroot-c tests/test-pull-c tests/test-repo tests/test-include-ostree-h tests/test-kargs
 
 if USE_AVAHI
 test_programs += tests/test-repo-finder-avahi
@@ -295,6 +295,10 @@ tests_test_repo_finder_avahi_CFLAGS = $(TESTS_CFLAGS)
 tests_test_repo_finder_avahi_LDADD = $(TESTS_LDADD)
 endif
 
+tests_test_kargs_SOURCES = src/libostree/ostree-kernel-args.c tests/test-kargs.c
+tests_test_kargs_CFLAGS = $(TESTS_CFLAGS)
+tests_test_kargs_LDADD = $(TESTS_LDADD)
+
 tests_test_repo_finder_config_SOURCES = tests/test-repo-finder-config.c
 tests_test_repo_finder_config_CFLAGS = $(TESTS_CFLAGS)
 tests_test_repo_finder_config_LDADD = $(TESTS_LDADD)
index d64ce451c112440cf2d60ffb03014743307a0d04..98a84d5f0d2b2363d77f16dd9096c6fb251a51c5 100644 (file)
@@ -78,7 +78,6 @@ IGNORE_HFILES= \
        ostree-fetcher.h \
        ostree-gpg-verifier.h \
        ostree-gpg-verify-result-private.h \
-       ostree-kernel-args.h \
        ostree-libarchive-input-stream.h \
        ostree-lzma-compressor.h \
        ostree-lzma-decompressor.h \
index 7a59b5a7b6ca4438510b907c92e7bfe82e5f359c..3838be4cb47fcaea52dc04cb180789ec6b583120 100644 (file)
@@ -669,3 +669,25 @@ ostree_repo_set_collection_ref_immediate
 ostree_repo_transaction_set_collection_ref
 ostree_repo_resolve_collection_ref
 </SECTION>
+
+<SECTION>
+<FILE>ostree-kernel-args</FILE>
+OstreeKernelArgs
+ostree_kernel_args_free
+ostree_kernel_args_new
+ostree_kernel_args_cleanup
+ostree_kernel_args_replace_take
+ostree_kernel_args_replace
+ostree_kernel_args_replace_argv
+ostree_kernel_args_append
+ostree_kernel_args_append_argv
+ostree_kernel_args_append_argv_filtered
+ostree_kernel_args_new_replace
+ostree_kernel_args_delete
+ostree_kernel_args_delete_key_entry
+ostree_kernel_args_append_proc_cmdline
+ostree_kernel_args_parse_append
+ostree_kernel_args_from_string
+ostree_kernel_args_to_strv
+ostree_kernel_args_to_string
+</SECTION>
index cdbdbb3200cf25295faf74f40e215e42cdd93b2e..125d94572e1d3266e79f15e2a76dcb8193923e09 100644 (file)
 LIBOSTREE_2019.3 {
 global:
   ostree_repo_write_archive_to_mtree_from_fd;
+  ostree_kernel_args_free;
+  ostree_kernel_args_new;
+  ostree_kernel_args_cleanup;
+  ostree_kernel_args_replace_take;
+  ostree_kernel_args_replace;
+  ostree_kernel_args_replace_argv;
+  ostree_kernel_args_append;
+  ostree_kernel_args_append_argv;
+  ostree_kernel_args_append_argv_filtered;
+  ostree_kernel_args_new_replace;
+  ostree_kernel_args_delete;
+  ostree_kernel_args_delete_key_entry;
+  ostree_kernel_args_append_proc_cmdline;
+  ostree_kernel_args_parse_append;
+  ostree_kernel_args_from_string;
+  ostree_kernel_args_to_strv;
+  ostree_kernel_args_to_string;
 } LIBOSTREE_2018.9;
 
 /* Stub section for the stable release *after* this development one; don't
index 87a938067825ad309d307f442ba1b8b042d80e9e..4cd955d5f4270c2afa788edc3a2b8388a914c49e 100644 (file)
@@ -78,8 +78,8 @@ append_system_uenv (OstreeBootloaderUboot   *self,
   const char *uenv_path = NULL;
   const char *ostree_arg = NULL;
 
-  kargs = _ostree_kernel_args_from_string (bootargs);
-  ostree_arg = _ostree_kernel_args_get_last_value (kargs, "ostree");
+  kargs = ostree_kernel_args_from_string (bootargs);
+  ostree_arg = ostree_kernel_args_get_last_value (kargs, "ostree");
   if (!ostree_arg)
     {
       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
index ac4014fa41d12a6c0a576df7e5f61ee746965621..dbf2ec8a112a3c5d65cebb2c6d0f7804630e47d9 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "ostree-kernel-args.h"
 #include "libglnx.h"
+#include "otutil.h"
 
 #include <string.h>
 
@@ -60,8 +61,24 @@ _arg_has_prefix (const char *arg,
   return FALSE;
 }
 
+static gboolean
+strcmp0_equal (gconstpointer v1,
+               gconstpointer v2)
+{
+  return g_strcmp0 (v1, v2) == 0;
+}
+
+/**
+ * ostree_kernel_args_new: (skip)
+ *
+ * Initializes a new OstreeKernelArgs structure and returns it
+ *
+ * Returns: (transfer full): A newly created #OstreeKernelArgs for kernel arguments
+ *
+ * Since: 2019.3
+ **/
 OstreeKernelArgs *
-_ostree_kernel_args_new (void)
+ostree_kernel_args_new (void)
 {
   OstreeKernelArgs *ret;
   ret = g_new0 (OstreeKernelArgs, 1);
@@ -71,8 +88,16 @@ _ostree_kernel_args_new (void)
   return ret;
 }
 
+/**
+ * ostree_kernel_args_free:
+ * @kargs: An OstreeKernelArgs that represents kernel arguments
+ *
+ * Frees the kargs structure
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_free (OstreeKernelArgs *kargs)
+ostree_kernel_args_free (OstreeKernelArgs *kargs)
 {
   if (!kargs)
     return;
@@ -81,9 +106,238 @@ _ostree_kernel_args_free (OstreeKernelArgs *kargs)
   g_free (kargs);
 }
 
+/**
+ * ostree_kernel_args_cleanup:
+ * @loc: Address of an OstreeKernelArgs pointer
+ *
+ * Frees the OstreeKernelArgs structure pointed by *loc
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_replace_take (OstreeKernelArgs   *kargs,
-                                  char               *arg)
+ostree_kernel_args_cleanup (void *loc)
+{
+  ostree_kernel_args_free (*((OstreeKernelArgs**)loc));
+}
+
+/**
+ * _ostree_kernel_arg_get_kargs_table:
+ * @kargs: An OstreeKernelArgs that represents kernel arguments
+ *
+ * Returns: (transfer none): #GHashTable that associates with the @kargs
+ *
+ * Note: this function is private for now, since the data structures underneath might be changed
+ *
+ * Since: 2019.3
+ **/
+GHashTable*
+_ostree_kernel_arg_get_kargs_table (OstreeKernelArgs *kargs)
+{
+  if (kargs != NULL)
+    return kargs->table;
+  return NULL;
+}
+
+/**
+ * _ostree_kernel_arg_get_key_array:
+ * @kargs: An OstreeKernelArgs that represents kernel arguments
+ *
+ * Returns: (transfer none) (element-type utf8): #GPtrArray that associates with @kargs
+ *
+ * Note: this function is private for now, since the data structures underneath might be changed
+ *
+ * Since: 2019.3
+ **/
+GPtrArray*
+_ostree_kernel_arg_get_key_array (OstreeKernelArgs *kargs)
+{
+  if (kargs != NULL)
+    return kargs->order;
+  return NULL;
+}
+
+/**
+ * ostree_kernel_args_new_replace:
+ * @kargs: OstreeKernelArgs instance
+ * @arg: a string argument
+ * @error: error instance
+ *
+ * This function implements the basic logic behind key/value pair
+ * replacement. Do note that the arg need to be properly formatted
+ *
+ * When replacing key with exact one value, the arg can be in
+ * the form:
+ * key, key=new_val, or key=old_val=new_val
+ * The first one swaps the old_val with the key to an empty value
+ * The second and third replace the old_val into the new_val
+ *
+ * When replacing key with multiple values, the arg can only be
+ * in the form of:
+ * key=old_val=new_val. Unless there is a special case where
+ * there is an empty value associated with the key, then
+ * key=new_val will work because old_val is empty. The empty
+ * val will be swapped with the new_val in that case
+ *
+ * Returns: %TRUE on success, %FALSE on failure (and in some other instances such as:
+ * 1. key not found in @kargs
+ * 2. old value not found when @arg is in the form of key=old_val=new_val
+ * 3. multiple old values found when @arg is in the form of key=old_val)
+ *
+ * Since: 2019.3
+ **/
+gboolean
+ostree_kernel_args_new_replace (OstreeKernelArgs *kargs,
+                                const char       *arg,
+                                GError          **error)
+{
+  g_autofree char *arg_owned = g_strdup (arg);
+  const char *key = arg_owned;
+  const char *val = split_keyeq (arg_owned);
+
+  GPtrArray *values = g_hash_table_lookup (kargs->table, key);
+  if (!values)
+    return glnx_throw (error, "No key '%s' found", key);
+  g_assert_cmpuint (values->len, >, 0);
+
+  /* first handle the case where the user just wants to replace an old value */
+  if (val && strchr (val, '='))
+    {
+      g_autofree char *old_val = g_strdup (val);
+      const char *new_val = split_keyeq (old_val);
+      g_assert (new_val);
+
+      guint i = 0;
+      if (!ot_ptr_array_find_with_equal_func (values, old_val, strcmp0_equal, &i))
+        return glnx_throw (error, "No karg '%s=%s' found", key, old_val);
+
+      g_clear_pointer (&values->pdata[i], g_free);
+      values->pdata[i] = g_strdup (new_val);
+      return TRUE;
+    }
+
+  /* can't know which val to replace without the old_val=new_val syntax */
+  if (values->len > 1)
+    return glnx_throw (error, "Multiple values for key '%s' found", key);
+
+  g_clear_pointer (&values->pdata[0], g_free);
+  values->pdata[0] = g_strdup (val);
+  return TRUE;
+}
+
+/**
+ * ostree_kernel_args_delete_key_entry
+ * @kargs: an OstreeKernelArgs instance
+ * @key: the key to remove
+ * @error: an GError instance
+ *
+ * This function removes the key entry from the hashtable
+ * as well from the order pointer array inside kargs
+ *
+ * Note: since both table and order inside kernel args
+ * are with free function, no extra free functions are
+ * being called as they are done automatically by GLib
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 2019.3
+ **/
+gboolean
+ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs,
+                                     const char       *key,
+                                     GError          **error)
+{
+  if (!g_hash_table_remove (kargs->table, key))
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Failed to find kernel argument '%s'",
+                   key);
+      return FALSE;
+    }
+
+  /* Then remove the key from order table */
+  guint key_index;
+  g_assert (ot_ptr_array_find_with_equal_func (kargs->order, key, g_str_equal, &key_index));
+  g_assert (g_ptr_array_remove_index (kargs->order, key_index));
+  return TRUE;
+}
+
+/**
+ *  ostree_kernel_args_delete:
+ *  @kargs: a OstreeKernelArgs instance
+ *  @arg: key or key/value pair for deletion
+ *  @error: an GError instance
+ *
+ *  There are few scenarios being handled for deletion:
+ *
+ *  1: for input arg with a single key(i.e without = for split),
+ *  the key/value pair will be deleted if there is only
+ *  one value that is associated with the key
+ *
+ *  2: for input arg wth key/value pair, the specific key
+ *  value pair will be deleted from the pointer array
+ *  if those exist.
+ *
+ *  3: If the found key has only one value
+ *  associated with it, the key entry in the table will also
+ *  be removed, and the key will be removed from order table
+ *
+ *  Returns: %TRUE on success, %FALSE on failure
+ *
+ *  Since: 2019.3
+ **/
+gboolean
+ostree_kernel_args_delete (OstreeKernelArgs  *kargs,
+                           const char        *arg,
+                           GError           **error)
+{
+  g_autofree char *arg_owned = g_strdup (arg);
+  const char *key = arg_owned;
+  const char *val = split_keyeq (arg_owned);
+
+  GPtrArray *values = g_hash_table_lookup (kargs->table, key);
+  if (!values)
+    return glnx_throw (error, "No key '%s' found", key);
+  g_assert_cmpuint (values->len, >, 0);
+
+  /* special-case: we allow deleting by key only if there's only one val */
+  if (values->len == 1)
+    {
+      /* but if a specific val was passed, check that it's the same */
+      if (val && !strcmp0_equal (val, values->pdata[0]))
+        return glnx_throw (error, "No karg '%s=%s' found", key, val);
+      return ostree_kernel_args_delete_key_entry (kargs, key, error);
+    }
+
+  /* note val might be NULL here, in which case we're looking for `key`, not `key=` or
+   * `key=val` */
+  guint i = 0;
+  if (!ot_ptr_array_find_with_equal_func (values, val, strcmp0_equal, &i))
+    {
+      if (!val)
+        /* didn't find NULL -> only key= key=val1 key=val2 style things left, so the user
+         * needs to be more specific */
+        return glnx_throw (error, "Multiple values for key '%s' found", arg);
+      return glnx_throw (error, "No karg '%s' found", arg);
+    }
+
+  g_ptr_array_remove_index (values, i);
+  return TRUE;
+}
+
+/**
+ * ostree_kernel_args_replace_take:
+ * @kargs: a OstreeKernelArgs instance
+ * @arg: (transfer full): key or key/value pair for replacement
+ *
+ * Finds and replaces the old key if @arg is already in the hash table,
+ * otherwise adds @arg as new key and split_keyeq (arg) as value.
+ * Note that when replacing old key, the old values are freed.
+ *
+ * Since: 2019.3
+ **/
+void
+ostree_kernel_args_replace_take (OstreeKernelArgs   *kargs,
+                                 char               *arg)
 {
   gboolean existed;
   GPtrArray *values = g_ptr_array_new_with_free_func (g_free);
@@ -105,16 +359,38 @@ _ostree_kernel_args_replace_take (OstreeKernelArgs   *kargs,
     }
 }
 
+/**
+ * ostree_kernel_args_replace:
+ * @kargs: a OstreeKernelArgs instance
+ * @arg: key or key/value pair for replacement
+ *
+ * Finds and replaces the old key if @arg is already in the hash table,
+ * otherwise adds @arg as new key and split_keyeq (arg) as value.
+ * Note that when replacing old key value pair, the old values are freed.
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_replace (OstreeKernelArgs  *kargs,
-                             const char        *arg)
+ostree_kernel_args_replace (OstreeKernelArgs  *kargs,
+                            const char        *arg)
 {
-  _ostree_kernel_args_replace_take (kargs, g_strdup (arg));
+  ostree_kernel_args_replace_take (kargs, g_strdup (arg));
 }
 
+/**
+ * ostree_kernel_args_append:
+ * @kargs: a OstreeKernelArgs instance
+ * @arg: key or key/value pair to be added
+ *
+ * Appends @arg which is in the form of key=value pair to the hash table kargs->table
+ * (appends to the value list if key is already in the hash table)
+ * and appends key to kargs->order if it is not in the hash table already.
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_append (OstreeKernelArgs  *kargs,
-                            const char        *arg)
+ostree_kernel_args_append (OstreeKernelArgs  *kargs,
+                           const char        *arg)
 {
   gboolean existed = TRUE;
   GPtrArray *values;
@@ -141,23 +417,44 @@ _ostree_kernel_args_append (OstreeKernelArgs  *kargs,
     }
 }
 
+/**
+ * ostree_kernel_args_replace_argv:
+ * @kargs: a OstreeKernelArgs instance
+ * @argv: an array of key or key/value pairs
+ *
+ * Finds and replaces each non-null arguments of @argv in the hash table,
+ * otherwise adds individual arg as new key and split_keyeq (arg) as value.
+ * Note that when replacing old key value pair, the old values are freed.
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_replace_argv (OstreeKernelArgs  *kargs,
-                                  char             **argv)
+ostree_kernel_args_replace_argv (OstreeKernelArgs  *kargs,
+                                 char             **argv)
 {
   char **strviter;
 
   for (strviter = argv; strviter && *strviter; strviter++)
     {
       const char *arg = *strviter;
-      _ostree_kernel_args_replace (kargs, arg);
+      ostree_kernel_args_replace (kargs, arg);
     }
 }
 
+/**
+ * ostree_kernel_args_append_argv_filtered:
+ * @kargs: a OstreeKernelArgs instance
+ * @argv: an array of key=value argument pairs
+ * @prefixes: an array of prefix strings
+ *
+ * Appends each argument that does not have one of the @prefixes as prefix to the @kargs
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_append_argv_filtered (OstreeKernelArgs  *kargs,
-                                          char             **argv,
-                                          char             **prefixes)
+ostree_kernel_args_append_argv_filtered (OstreeKernelArgs  *kargs,
+                                         char             **argv,
+                                         char             **prefixes)
 {
   char **strviter;
 
@@ -166,21 +463,44 @@ _ostree_kernel_args_append_argv_filtered (OstreeKernelArgs  *kargs,
       const char *arg = *strviter;
 
       if (!_arg_has_prefix (arg, prefixes))
-        _ostree_kernel_args_append (kargs, arg);
+        ostree_kernel_args_append (kargs, arg);
     }
 }
 
+/**
+ * ostree_kernel_args_append_argv:
+ * @kargs: a OstreeKernelArgs instance
+ * @argv: an array of key=value argument pairs
+ *
+ * Appends each value in @argv to the corresponding value array and
+ * appends key to kargs->order if it is not in the hash table already.
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_append_argv (OstreeKernelArgs  *kargs,
-                                 char             **argv)
+ostree_kernel_args_append_argv (OstreeKernelArgs  *kargs,
+                                char             **argv)
 {
-  _ostree_kernel_args_append_argv_filtered (kargs, argv, NULL);
+  ostree_kernel_args_append_argv_filtered (kargs, argv, NULL);
 }
 
+/**
+ * ostree_kernel_args_append_proc_cmdline:
+ * @kargs: a OstreeKernelArgs instance
+ * @cancellable: optional GCancellable object, NULL to ignore
+ * @error: an GError instance
+ *
+ * Appends the command line arguments in the file "/proc/cmdline"
+ * that does not have "BOOT_IMAGE=" and "initrd=" as prefixes to the @kargs
+ *
+ * Returns: %TRUE on success, %FALSE on failure
+ *
+ * Since: 2019.3
+ **/
 gboolean
-_ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs,
-                                         GCancellable     *cancellable,
-                                         GError          **error)
+ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs,
+                                        GCancellable     *cancellable,
+                                        GError          **error)
 {
   g_autoptr(GFile) proc_cmdline_path = g_file_new_for_path ("/proc/cmdline");
   g_autofree char *proc_cmdline = NULL;
@@ -202,44 +522,76 @@ _ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs,
   g_strchomp (proc_cmdline);
 
   proc_cmdline_args = g_strsplit (proc_cmdline, " ", -1);
-  _ostree_kernel_args_append_argv_filtered (kargs, proc_cmdline_args,
+  ostree_kernel_args_append_argv_filtered (kargs, proc_cmdline_args,
                                             filtered_prefixes);
 
   return TRUE;
 }
 
+/**
+ * ostree_kernel_args_parse_append:
+ * @kargs: a OstreeKernelArgs instance
+ * @options: a string representing command line arguments
+ *
+ * Parses @options by separating it by whitespaces and appends each argument to @kargs
+ *
+ * Since: 2019.3
+ **/
 void
-_ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
-                                  const char       *options)
+ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
+                                 const char       *options)
 {
   char **args = NULL;
   char **iter;
 
   if (!options)
     return;
-  
+
   args = g_strsplit (options, " ", -1);
   for (iter = args; *iter; iter++)
     {
       char *arg = *iter;
-      _ostree_kernel_args_append (kargs, arg);
+      ostree_kernel_args_append (kargs, arg);
     }
   g_strfreev (args);
 }
 
+/**
+ * ostree_kernel_args_from_string: (skip)
+ * @options: a string representing command line arguments
+ *
+ * Initializes a new OstreeKernelArgs then parses and appends @options
+ * to the empty OstreeKernelArgs
+ *
+ * Returns: (transfer full): newly allocated #OstreeKernelArgs with @options appended
+ *
+ * Since: 2019.3
+ **/
 OstreeKernelArgs *
-_ostree_kernel_args_from_string (const char *options)
+ostree_kernel_args_from_string (const char *options)
 {
   OstreeKernelArgs *ret;
 
-  ret = _ostree_kernel_args_new ();
-  _ostree_kernel_args_parse_append (ret, options);
+  ret = ostree_kernel_args_new ();
+  ostree_kernel_args_parse_append (ret, options);
 
   return ret;
 }
 
+/**
+ * ostree_kernel_args_to_strv:
+ * @kargs: a OstreeKernelArgs instance
+ *
+ * Extracts all key value pairs in @kargs and appends to a temporary
+ * array in forms of "key=value" or "key" if value is NULL, and returns
+ * the temporary array with the GPtrArray wrapper freed
+ *
+ * Returns: (transfer full): an array of "key=value" pairs or "key" if value is NULL
+ *
+ * Since: 2019.3
+ **/
 char **
-_ostree_kernel_args_to_strv (OstreeKernelArgs *kargs)
+ostree_kernel_args_to_strv (OstreeKernelArgs *kargs)
 {
   GPtrArray *strv = g_ptr_array_new ();
   guint i;
@@ -266,8 +618,25 @@ _ostree_kernel_args_to_strv (OstreeKernelArgs *kargs)
   return (char**)g_ptr_array_free (strv, FALSE);
 }
 
+/**
+ * ostree_kernel_args_to_string:
+ * @kargs: a OstreeKernelArgs instance
+ *
+ * Extracts all key value pairs in @kargs and appends to a temporary
+ * GString in forms of "key=value" or "key" if value is NULL separated
+ * by a single whitespace, and returns the temporary string with the
+ * GString wrapper freed
+ *
+ * Note: the application will be terminated if one of the values array
+ * in @kargs is NULL
+ *
+ * Returns: (transfer full): a string of "key=value" pairs or "key" if value is NULL,
+ * separated by single whitespaces
+ *
+ * Since: 2019.3
+ **/
 char *
-_ostree_kernel_args_to_string (OstreeKernelArgs *kargs)
+ostree_kernel_args_to_string (OstreeKernelArgs *kargs)
 {
   GString *buf = g_string_new ("");
   gboolean first = TRUE;
@@ -302,8 +671,22 @@ _ostree_kernel_args_to_string (OstreeKernelArgs *kargs)
   return g_string_free (buf, FALSE);
 }
 
+/**
+ * ostree_kernel_args_get_last_value:
+ * @kargs: a OstreeKernelArgs instance
+ * @key: a key to look for in @kargs hash table
+ *
+ * Finds and returns the last element of value array
+ * corresponding to the @key in @kargs hash table. Note that the application
+ * will be terminated if the @key is found but the value array is empty
+ *
+ * Returns: NULL if @key is not found in the @kargs hash table,
+ * otherwise returns last element of value array corresponding to @key
+ *
+ * Since: 2019.3
+ **/
 const char *
-_ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
+ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
 {
   GPtrArray *values = g_hash_table_lookup (kargs->table, key);
 
index 0bc43704a57dc4215aaeac76321165d206696718..d7beca516f79ca20d5a8bcbe47dc719c7147d798 100644 (file)
 
 #pragma once
 
-#include "libglnx.h"
+#include <gio/gio.h>
+#include <glib.h>
+#include <glib-object.h>
+#include "ostree-types.h"
 
 G_BEGIN_DECLS
 
 typedef struct _OstreeKernelArgs OstreeKernelArgs;
-void _ostree_kernel_args_free (OstreeKernelArgs *kargs);
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeKernelArgs, _ostree_kernel_args_free);
-
-OstreeKernelArgs *_ostree_kernel_args_new (void);
-void _ostree_kernel_args_replace_take (OstreeKernelArgs  *kargs,
-                                       char              *key);
-void _ostree_kernel_args_replace (OstreeKernelArgs  *kargs,
-                                  const char        *key);
-void _ostree_kernel_args_replace_argv (OstreeKernelArgs  *kargs,
-                                       char             **argv);
-void _ostree_kernel_args_append (OstreeKernelArgs  *kargs,
-                                 const char     *key);
-void _ostree_kernel_args_append_argv (OstreeKernelArgs  *kargs,
-                                      char **argv);
-void _ostree_kernel_args_append_argv_filtered (OstreeKernelArgs  *kargs,
-                                               char **argv,
-                                               char **prefixes);
-
-gboolean _ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs,
-                                                  GCancellable     *cancellable,
-                                                  GError          **error);
-
-void _ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
-                                       const char *options);
-
-const char *_ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key);
-
-OstreeKernelArgs * _ostree_kernel_args_from_string (const char *options);
-
-char ** _ostree_kernel_args_to_strv (OstreeKernelArgs *kargs);
-char * _ostree_kernel_args_to_string (OstreeKernelArgs *kargs);
+
+GHashTable *_ostree_kernel_arg_get_kargs_table (OstreeKernelArgs *kargs);
+
+GPtrArray *_ostree_kernel_arg_get_key_array (OstreeKernelArgs *kargs);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_free (OstreeKernelArgs *kargs);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(OstreeKernelArgs, ostree_kernel_args_free)
+
+_OSTREE_PUBLIC
+OstreeKernelArgs *ostree_kernel_args_new (void);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_cleanup (void *loc);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_replace_take (OstreeKernelArgs  *kargs,
+                                      char              *arg);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_replace (OstreeKernelArgs  *kargs,
+                                 const char        *arg);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_replace_argv (OstreeKernelArgs  *kargs,
+                                      char             **argv);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_append (OstreeKernelArgs  *kargs,
+                                const char     *arg);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_append_argv (OstreeKernelArgs  *kargs,
+                                     char **argv);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_append_argv_filtered (OstreeKernelArgs  *kargs,
+                                              char **argv,
+                                              char **prefixes);
+
+_OSTREE_PUBLIC
+gboolean ostree_kernel_args_new_replace (OstreeKernelArgs *kargs,
+                                         const char       *arg,
+                                         GError          **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_kernel_args_delete (OstreeKernelArgs *kargs,
+                                    const char       *arg,
+                                    GError           **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_kernel_args_delete_key_entry (OstreeKernelArgs *kargs,
+                                              const char       *key,
+                                              GError          **error);
+
+_OSTREE_PUBLIC
+gboolean ostree_kernel_args_append_proc_cmdline (OstreeKernelArgs *kargs,
+                                                 GCancellable     *cancellable,
+                                                 GError          **error);
+
+_OSTREE_PUBLIC
+void ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
+                                      const char *options);
+
+_OSTREE_PUBLIC
+const char *ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs,
+                                               const char *key);
+
+_OSTREE_PUBLIC
+OstreeKernelArgs *ostree_kernel_args_from_string (const char *options);
+
+_OSTREE_PUBLIC
+char **ostree_kernel_args_to_strv (OstreeKernelArgs *kargs);
+
+_OSTREE_PUBLIC
+char *ostree_kernel_args_to_string (OstreeKernelArgs *kargs);
 
 G_END_DECLS
index 1096b0b071191a1f9d90a3becd47216733cadaa3..d47f64380024c83fc50aa2e90b2ed1440ddd7644 100644 (file)
@@ -1759,7 +1759,7 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
   ostree_bootconfig_parser_set (bootconfig, "linux", boot_relpath);
 
   val = ostree_bootconfig_parser_get (bootconfig, "options");
-  g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_from_string (val);
+  g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (val);
 
   if (kernel_layout->initramfs_namever)
     {
@@ -1772,7 +1772,7 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
       prepare_root_arg = g_strdup_printf ("init=/ostree/boot.%d/%s/%s/%d/usr/lib/ostree/ostree-prepare-root",
                                              new_bootversion, osname, bootcsum,
                                              ostree_deployment_get_bootserial (deployment));
-      _ostree_kernel_args_replace_take (kargs, g_steal_pointer (&prepare_root_arg));
+      ostree_kernel_args_replace_take (kargs, g_steal_pointer (&prepare_root_arg));
     }
 
   if (kernel_layout->devicetree_namever)
@@ -1785,9 +1785,9 @@ install_deployment_kernel (OstreeSysroot   *sysroot,
   g_autofree char *ostree_kernel_arg = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d",
                                        new_bootversion, osname, bootcsum,
                                        ostree_deployment_get_bootserial (deployment));
-  _ostree_kernel_args_replace_take (kargs, g_steal_pointer (&ostree_kernel_arg));
+  ostree_kernel_args_replace_take (kargs, g_steal_pointer (&ostree_kernel_arg));
 
-  g_autofree char *options_key = _ostree_kernel_args_to_string (kargs);
+  g_autofree char *options_key = ostree_kernel_args_to_string (kargs);
   ostree_bootconfig_parser_set (bootconfig, "options", options_key);
 
   glnx_autofd int bootconf_dfd = -1;
@@ -1895,9 +1895,9 @@ get_deployment_nonostree_kargs (OstreeDeployment *deployment)
   /* pick up kernel arguments but filter out ostree= */
   OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (deployment);
   const char *boot_options = ostree_bootconfig_parser_get (bootconfig, "options");
-  g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_from_string (boot_options);
-  _ostree_kernel_args_replace (kargs, "ostree");
-  return _ostree_kernel_args_to_string (kargs);
+  g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_from_string (boot_options);
+  ostree_kernel_args_replace (kargs, "ostree");
+  return ostree_kernel_args_to_string (kargs);
 }
 
 static char*
@@ -2463,9 +2463,9 @@ _ostree_deployment_set_bootconfig_from_kargs (OstreeDeployment *deployment,
    */
   if (override_kernel_argv)
     {
-      g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_new ();
-      _ostree_kernel_args_append_argv (kargs, override_kernel_argv);
-      g_autofree char *new_options = _ostree_kernel_args_to_string (kargs);
+      g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_new ();
+      ostree_kernel_args_append_argv (kargs, override_kernel_argv);
+      g_autofree char *new_options = ostree_kernel_args_to_string (kargs);
       ostree_bootconfig_parser_set (bootconfig, "options", new_options);
     }
 }
@@ -3004,9 +3004,9 @@ ostree_sysroot_deployment_set_kargs (OstreeSysroot     *self,
   g_autoptr(OstreeDeployment) new_deployment = ostree_deployment_clone (deployment);
   OstreeBootconfigParser *new_bootconfig = ostree_deployment_get_bootconfig (new_deployment);
 
-  g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_new ();
-  _ostree_kernel_args_append_argv (kargs, new_kargs);
-  g_autofree char *new_options = _ostree_kernel_args_to_string (kargs);
+  g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_new ();
+  ostree_kernel_args_append_argv (kargs, new_kargs);
+  g_autofree char *new_options = ostree_kernel_args_to_string (kargs);
   ostree_bootconfig_parser_set (new_bootconfig, "options", new_options);
 
   g_autoptr(GPtrArray) new_deployments = g_ptr_array_new_with_free_func (g_object_unref);
index e4b2039e2fa7a13ac8a5612b7028eb26ed9092d7..858673c5d3118c2023c0de4dd676385b1acad602 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "libglnx.h"
 #include "ostree.h"
-#include "ostree-kernel-args.h"
 #include "ostree-bootloader.h"
 
 G_BEGIN_DECLS
index 4862b7b4d9f6ce3cd6daefda89ef59a4a27b5d58..b3ad2498aeabe4a5fb4b7da9e15664cdd543f7a5 100644 (file)
@@ -1688,12 +1688,12 @@ clone_deployment (OstreeSysroot  *sysroot,
   /* Copy the bootloader config options */
   OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
   g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);
-  g_autoptr(OstreeKernelArgs) kargs = _ostree_kernel_args_new ();
-  _ostree_kernel_args_append_argv (kargs, previous_args);
+  g_autoptr(OstreeKernelArgs) kargs = ostree_kernel_args_new ();
+  ostree_kernel_args_append_argv (kargs, previous_args);
 
   /* Deploy the copy */
   g_autoptr(OstreeDeployment) new_deployment = NULL;
-  g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs);
+  g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs);
   if (!ostree_sysroot_deploy_tree (sysroot,
                                    ostree_deployment_get_osname (target_deployment),
                                    ostree_deployment_get_csum (target_deployment),
index cbeb99b24638a77b79b37aab88da64b3e45efba4..ca19bc853d5b340e13c429562be56fb8a201302b 100644 (file)
@@ -41,3 +41,4 @@
 #include <ostree-repo-finder-override.h>
 #include <ostree-autocleanups.h>
 #include <ostree-version.h>
+#include <ostree-kernel-args.h>
index d6f37bc9e55418a3bd8fcecbc297fd8e753a1f40..35e6a34365f4cd93782436749e36e4a9b0ac2e42 100644 (file)
@@ -62,3 +62,55 @@ ot_parse_keyvalue (const char  *keyvalue,
   *out_value = g_strdup (eq + 1);
   return TRUE;
 }
+
+/**
+ * Note: temporarily copied from GLib: https://github.com/GNOME/glib/blob/a419146578a42c760cff684292465b38df855f75/glib/garray.c#L1664
+ * See documentation at: https://developer.gnome.org/glib/stable/glib-Pointer-Arrays.html#g-ptr-array-find-with-equal-func
+ *
+ * ot_ptr_array_find_with_equal_func: (skip)
+ * @haystack: pointer array to be searched
+ * @needle: pointer to look for
+ * @equal_func: (nullable): the function to call for each element, which should
+ *    return %TRUE when the desired element is found; or %NULL to use pointer
+ *    equality
+ * @index_: (optional) (out caller-allocates): return location for the index of
+ *    the element, if found
+ *
+ * Checks whether @needle exists in @haystack, using the given @equal_func.
+ * If the element is found, %TRUE is returned and the element’s index is
+ * returned in @index_ (if non-%NULL). Otherwise, %FALSE is returned and @index_
+ * is undefined. If @needle exists multiple times in @haystack, the index of
+ * the first instance is returned.
+ *
+ * @equal_func is called with the element from the array as its first parameter,
+ * and @needle as its second parameter. If @equal_func is %NULL, pointer
+ * equality is used.
+ *
+ * Returns: %TRUE if @needle is one of the elements of @haystack
+ * Since: 2.54
+ */
+gboolean
+ot_ptr_array_find_with_equal_func (GPtrArray     *haystack,
+                                   gconstpointer  needle,
+                                   GEqualFunc     equal_func,
+                                   guint         *index_)
+{
+  guint i;
+
+  g_return_val_if_fail (haystack != NULL, FALSE);
+
+  if (equal_func == NULL)
+    equal_func = g_direct_equal;
+
+  for (i = 0; i < haystack->len; i++)
+    {
+      if (equal_func (g_ptr_array_index (haystack, i), needle))
+        {
+          if (index_ != NULL)
+            *index_ = i;
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
index e3381730fadb4bc1d33b05e138520bbf82a89588..70f7d55dd08a21d15b9891c8f70d5f4ba13a840e 100644 (file)
@@ -34,5 +34,10 @@ ot_parse_keyvalue (const char  *keyvalue,
                    char       **out_key,
                    char       **out_value,
                    GError     **error);
+gboolean
+ot_ptr_array_find_with_equal_func (GPtrArray     *haystack,
+                                   gconstpointer  needle,
+                                   GEqualFunc     equal_func,
+                                   guint         *index_);
 
 G_END_DECLS
index eced95f9eaf0cee8497a8efb415d580bfc969a8e..8f1bd4e7e3fa08d649771b3c96ffb86bf4791184 100644 (file)
@@ -62,3 +62,4 @@
 #include <ot-checksum-utils.h>
 #include <ot-gpg-utils.h>
 #include <ot-checksum-instream.h>
+#include <ot-tool-util.h>
index 38ec923f7e6913e101f21e85ee51d840ad815357..c1c3353de0d00eacca815608ed1784dac099faf2 100644 (file)
@@ -29,8 +29,6 @@
 #include "ostree.h"
 #include "otutil.h"
 
-#include "../libostree/ostree-kernel-args.h"
-
 #include <glib/gi18n.h>
 
 static gboolean opt_retain;
@@ -133,20 +131,20 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat
   g_autoptr(OstreeKernelArgs) kargs = NULL;
   if (opt_kernel_arg_none)
     {
-      kargs = _ostree_kernel_args_new ();
+      kargs = ostree_kernel_args_new ();
     }
   else if (opt_kernel_proc_cmdline)
     {
-      kargs = _ostree_kernel_args_new ();
-      if (!_ostree_kernel_args_append_proc_cmdline (kargs, cancellable, error))
+      kargs = ostree_kernel_args_new ();
+      if (!ostree_kernel_args_append_proc_cmdline (kargs, cancellable, error))
         return FALSE;
     }
   else if (merge_deployment && (opt_kernel_argv || opt_kernel_argv_append))
     {
       OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
       g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);
-      kargs = _ostree_kernel_args_new ();
-      _ostree_kernel_args_append_argv (kargs, previous_args);
+      kargs = ostree_kernel_args_new ();
+      ostree_kernel_args_append_argv (kargs, previous_args);
     }
 
   /* Now replace/extend the above set.  Note that if no options are specified,
@@ -156,19 +154,19 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeCommandInvocation *invocat
   if (opt_kernel_argv)
     {
       if (!kargs)
-        kargs = _ostree_kernel_args_new ();
-      _ostree_kernel_args_replace_argv (kargs, opt_kernel_argv);
+        kargs = ostree_kernel_args_new ();
+      ostree_kernel_args_replace_argv (kargs, opt_kernel_argv);
     }
 
   if (opt_kernel_argv_append)
     {
       if (!kargs)
-        kargs = _ostree_kernel_args_new ();
-      _ostree_kernel_args_append_argv (kargs, opt_kernel_argv_append);
+        kargs = ostree_kernel_args_new ();
+      ostree_kernel_args_append_argv (kargs, opt_kernel_argv_append);
     }
 
   g_autoptr(OstreeDeployment) new_deployment = NULL;
-  g_auto(GStrv) kargs_strv = kargs ? _ostree_kernel_args_to_strv (kargs) : NULL;
+  g_auto(GStrv) kargs_strv = kargs ? ostree_kernel_args_to_strv (kargs) : NULL;
   if (opt_stage)
     {
       if (opt_retain_pending || opt_retain_rollback)
index f0efa44ab87fc9f2f96bdfea3d5f34dba17ea0cc..cd46618301b586fc40ce66c92494b89028841d62 100644 (file)
@@ -27,8 +27,6 @@
 #include "ostree.h"
 #include "otutil.h"
 
-#include "../libostree/ostree-kernel-args.h"
-
 #include <glib/gi18n.h>
 #include <err.h>
 
index 666e536904dd58741a69f18c03be11bad6fc071b..fb5c7d2d6b9e7922fd3f99292bbca3455230aa75 100644 (file)
@@ -26,8 +26,7 @@
 #include "ot-admin-instutil-builtins.h"
 
 #include "otutil.h"
-
-#include "../libostree/ostree-kernel-args.h"
+#include "ostree.h"
 
 static gboolean opt_proc_cmdline;
 static gboolean opt_merge;
@@ -69,14 +68,14 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocat
     }
   first_deployment = deployments->pdata[0];
 
-  kargs = _ostree_kernel_args_new ();
+  kargs = ostree_kernel_args_new ();
 
   /* If they want the current kernel's args, they very likely don't
    * want the ones from the merge.
    */
   if (opt_proc_cmdline)
     {
-      if (!_ostree_kernel_args_append_proc_cmdline (kargs, cancellable, error))
+      if (!ostree_kernel_args_append_proc_cmdline (kargs, cancellable, error))
         goto out;
     }
   else if (opt_merge)
@@ -84,24 +83,24 @@ ot_admin_instutil_builtin_set_kargs (int argc, char **argv, OstreeCommandInvocat
       OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (first_deployment);
       g_auto(GStrv) previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);
 
-      _ostree_kernel_args_append_argv (kargs, previous_args);
+      ostree_kernel_args_append_argv (kargs, previous_args);
     }
 
   if (opt_replace)
     {
-      _ostree_kernel_args_replace_argv (kargs, opt_replace);
+      ostree_kernel_args_replace_argv (kargs, opt_replace);
     }
 
   if (opt_append)
     {
-      _ostree_kernel_args_append_argv (kargs, opt_append);
+      ostree_kernel_args_append_argv (kargs, opt_append);
     }
 
   for (i = 1; i < argc; i++)
-    _ostree_kernel_args_append (kargs, argv[i]);
+    ostree_kernel_args_append (kargs, argv[i]);
 
   {
-    g_auto(GStrv) kargs_strv = _ostree_kernel_args_to_strv (kargs);
+    g_auto(GStrv) kargs_strv = ostree_kernel_args_to_strv (kargs);
 
     if (!ostree_sysroot_deployment_set_kargs (sysroot, first_deployment,
                                               kargs_strv,
index 8f03c0260f88abdab3af0ce526a0e83c27892ec0..f5e95e49f60a7b9a9ff403be711c9bbb29c84a7e 100644 (file)
@@ -22,3 +22,4 @@ test-repo-finder-avahi
 test-repo-finder-config
 test-repo-finder-mount
 test-rollsum-cli
+test-kargs
diff --git a/tests/test-kargs.c b/tests/test-kargs.c
new file mode 100644 (file)
index 0000000..8d34f73
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.0+
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "ostree-kernel-args.h"
+#include "otutil.h"
+
+static gboolean
+check_string_existance (OstreeKernelArgs *karg,
+                        const char *string_to_find)
+{
+  g_autofree gchar* string_with_spaces = ostree_kernel_args_to_string (karg);
+  g_auto(GStrv) string_list = g_strsplit (string_with_spaces, " ", -1);
+  return g_strv_contains ((const char* const*) string_list, string_to_find);
+}
+
+static void
+test_kargs_delete (void)
+{
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+  __attribute__((cleanup(ostree_kernel_args_cleanup))) OstreeKernelArgs *karg = ostree_kernel_args_new ();
+
+  ostree_kernel_args_append (karg, "single_key=test");
+  ostree_kernel_args_append (karg, "test=firstval");
+  ostree_kernel_args_append (karg, "test=secondval");
+  ostree_kernel_args_append (karg, "test=");
+  ostree_kernel_args_append (karg, "test");
+
+  /* Delete a non-existant key should fail */
+  ret = ostree_kernel_args_delete (karg, "non_existant_key", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Delete a key with multiple values when only specifying key should work if a no-value
+   * variant exists */
+  ret = ostree_kernel_args_delete (karg, "test", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "test"));
+
+  /* Trying again now should fail since there are only kargs with various values */
+  ret = ostree_kernel_args_delete (karg, "test", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Delete a key with a non existant value should fail */
+  ret = ostree_kernel_args_delete (karg, "test=non_existant_value", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Delete a key with only one value should fail if the value doesn't match */
+  ret = ostree_kernel_args_delete (karg, "single_key=non_existent_value", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Delete a key with only one value should succeed by only specifying key */
+  ret = ostree_kernel_args_delete (karg, "single_key", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  /* verify the value array is properly updated */
+  GPtrArray *kargs_array = _ostree_kernel_arg_get_key_array (karg);
+  g_assert (!ot_ptr_array_find_with_equal_func (kargs_array, "single_key", g_str_equal, NULL));
+  g_assert (!check_string_existance (karg, "single_key"));
+
+  /* Delete specific key/value pair */
+  ret = ostree_kernel_args_delete (karg, "test=secondval", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "test=secondval"));
+
+  /* Delete key/value pair with empty string value */
+  ret = ostree_kernel_args_delete (karg, "test=", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "test="));
+
+  ret = ostree_kernel_args_delete (karg, "test=firstval", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "test=firstval"));
+
+  /* Check that we can delete duplicate keys */
+  ostree_kernel_args_append (karg, "test=foo");
+  ostree_kernel_args_append (karg, "test=foo");
+  check_string_existance (karg, "test=foo");
+  ret = ostree_kernel_args_delete (karg, "test=foo", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (check_string_existance (karg, "test=foo"));
+  ret = ostree_kernel_args_delete (karg, "test=foo", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "test=foo"));
+
+  /* Make sure we also gracefully do this for key-only args */
+  ostree_kernel_args_append (karg, "nosmt");
+  ostree_kernel_args_append (karg, "nosmt");
+  check_string_existance (karg, "nosmt");
+  ret = ostree_kernel_args_delete (karg, "nosmt", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (check_string_existance (karg, "nosmt"));
+  ret = ostree_kernel_args_delete (karg, "nosmt", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "nosmt"));
+}
+
+static void
+test_kargs_replace (void)
+{
+  g_autoptr(GError) error = NULL;
+  gboolean ret;
+  __attribute__((cleanup(ostree_kernel_args_cleanup))) OstreeKernelArgs *karg = ostree_kernel_args_new ();
+
+  ostree_kernel_args_append (karg, "single_key");
+  ostree_kernel_args_append (karg, "test=firstval");
+  ostree_kernel_args_append (karg, "test=secondval");
+
+  /* Replace when the input key is non-existant should fail */
+  ret = ostree_kernel_args_new_replace (karg, "nonexistantkey", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Replace non-existant value with input key=nonexistantvalue=newvalue should fail */
+  ret = ostree_kernel_args_new_replace (karg, "single_key=nonexistantval=newval", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Replace with input key=value will fail for a key with multiple values */
+  ret = ostree_kernel_args_new_replace (karg, "test=newval", &error);
+  g_assert (!ret);
+  g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
+  g_clear_error (&error);
+
+  /* Replace with input key=value for a key with single value should succeed
+   * Also note, we also allow ''(empty string) valid to be a value
+   */
+  ret = ostree_kernel_args_new_replace (karg, "single_key=newvalue", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "single_key"));
+  g_assert (check_string_existance (karg, "single_key=newvalue"));
+
+  /* Replace with input key=value=newvalue if key and value both
+   * exist, the action should succeed
+   */
+  ret = ostree_kernel_args_new_replace (karg, "test=firstval=newval", &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+  g_assert (!check_string_existance (karg, "test=firstval"));
+  g_assert (check_string_existance (karg, "test=newval"));
+}
+
+static gboolean
+strcmp0_equal (gconstpointer v1,
+               gconstpointer v2)
+{
+  return g_strcmp0 (v1, v2) == 0;
+}
+
+/* In this function, we want to verify that ostree_kernel_args_append
+ * and ostree_kernel_args_to_string is correct. After that
+ * we will use these two functions(append and tostring) in other tests: delete and replace
+ */
+static void
+test_kargs_append (void)
+{
+  __attribute__((cleanup(ostree_kernel_args_cleanup))) OstreeKernelArgs *append_arg = ostree_kernel_args_new ();
+  /* Some valid cases (key=value) pair */
+  ostree_kernel_args_append (append_arg, "test=valid");
+  ostree_kernel_args_append (append_arg, "test=secondvalid");
+  ostree_kernel_args_append (append_arg, "test=");
+  ostree_kernel_args_append (append_arg, "test");
+  ostree_kernel_args_append (append_arg, "second_test");
+
+  /* We loops through the kargs inside table to verify
+   * the functionality of append because at this stage
+   * we have yet to find the conversion kargs to string fully "functional"
+   */
+  GHashTable *kargs_table = _ostree_kernel_arg_get_kargs_table (append_arg);
+  GLNX_HASH_TABLE_FOREACH_KV (kargs_table, const char*, key, GPtrArray*, value_array)
+    {
+      if (g_str_equal (key, "test"))
+        {
+          g_assert (ot_ptr_array_find_with_equal_func (value_array, "valid", strcmp0_equal, NULL));
+          g_assert (ot_ptr_array_find_with_equal_func (value_array, "secondvalid", strcmp0_equal, NULL));
+          g_assert (ot_ptr_array_find_with_equal_func (value_array, "", strcmp0_equal, NULL));
+          g_assert (ot_ptr_array_find_with_equal_func (value_array, NULL, strcmp0_equal, NULL));
+        }
+      else
+        {
+          g_assert_cmpstr (key, ==, "second_test");
+          g_assert (ot_ptr_array_find_with_equal_func (value_array, NULL, strcmp0_equal, NULL));
+        }
+    }
+
+  /* verify the value array is properly updated */
+  GPtrArray *kargs_array = _ostree_kernel_arg_get_key_array (append_arg);
+  g_assert (ot_ptr_array_find_with_equal_func (kargs_array, "test", g_str_equal, NULL));
+  g_assert (ot_ptr_array_find_with_equal_func (kargs_array, "second_test", g_str_equal, NULL));
+
+  /* Up till this point, we verified that the above was all correct, we then
+   * check ostree_kernel_args_to_string has the right result
+   */
+  g_autofree gchar* kargs_str = ostree_kernel_args_to_string (append_arg);
+  g_auto(GStrv) kargs_list = g_strsplit(kargs_str, " ", -1);
+  g_assert (g_strv_contains ((const char* const *)kargs_list, "test=valid"));
+  g_assert (g_strv_contains ((const char* const *)kargs_list, "test=secondvalid"));
+  g_assert (g_strv_contains ((const char* const *)kargs_list, "test="));
+  g_assert (g_strv_contains ((const char* const *)kargs_list, "test"));
+  g_assert (g_strv_contains ((const char* const *)kargs_list, "second_test"));
+  g_assert_cmpint (5, ==, g_strv_length (kargs_list));
+}
+
+int
+main (int argc,
+      char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/kargs/kargs_append", test_kargs_append);
+  g_test_add_func ("/kargs/kargs_delete", test_kargs_delete);
+  g_test_add_func ("/kargs/kargs_replace", test_kargs_replace);
+  return g_test_run ();
+}